package com.seguriapp.dao;

import static org.hibernate.criterion.Restrictions.eq;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.springframework.stereotype.Repository;

import com.seguriapp.base.GenericDaoImpl;
import com.seguriapp.entities.User;
import com.seguriapp.entities.UserSeguriAppEntity;

/**
 * Data access object for {@link User} entities using Hibernate.
 * 
 * @author Tania Gonzales (taniadgv@gmail.com)
 */
@Repository
public class UserDaoImpl extends GenericDaoImpl<User> implements UserDao {

  private static final String USERNAME_FIELD = "username";

  public UserDaoImpl() {
    super(User.class);
  }

  public User getUserInitialData(final User user) {

    return (User) getSession().createCriteria(User.class).add(eq(USERNAME_FIELD, user.getUsername()).ignoreCase()).add(eq("password", user.getPassword()))
        .uniqueResult();

  }

  public long getUsersTotalPages(final int pageSize) {
    final Criteria criteria = getSession().createCriteria(User.class);
    criteria.setProjection(Projections.rowCount());
    final long total = Long.valueOf(criteria.uniqueResult().toString());
    long pages = 0;
    if (pageSize != 0) {
      pages = total / pageSize;
      if (total % pageSize > 0) {
        pages++;
      }
    }
    return pages;
  }

  @SuppressWarnings("unchecked")
  public List<User> listUsersOrderByColumn(final int page, final int pageSize, final boolean ascending, final String columnSort) {
    final Criteria criteria = getSession().createCriteria(User.class);
    if (columnSort != null) {
      if (ascending) {
        criteria.addOrder(Order.asc(columnSort));
      } else {
        criteria.addOrder(Order.desc(columnSort));
      }
    } else {
      criteria.addOrder(Order.asc(USERNAME_FIELD));
    }
    return criteria.setMaxResults(pageSize).setFirstResult((page - 1) * pageSize).list();
  }

  public boolean isValidUserName(final String username) {
    final Criteria criteria = getSession().createCriteria(User.class).add(eq(USERNAME_FIELD, username));
    criteria.setProjection(Projections.rowCount());
    final long total = Long.valueOf(criteria.uniqueResult().toString());
    return total == 0;
  }

  @SuppressWarnings("unchecked")
  public List<Long> getUserEntities(final Long userId) {
    final Criteria criteria = getSession().createCriteria(UserSeguriAppEntity.class).add(eq("user.id", userId));
    criteria.setProjection(Projections.property("entity.id"));
    return criteria.list();
  }

  public boolean isUserAdmin(final Long userId) {
    final Criteria criteria = getSession().createCriteria(User.class).add(eq("id", userId)).add(eq("administrator", true));
    criteria.setProjection(Projections.rowCount());
    final int total = Integer.valueOf(criteria.uniqueResult().toString());
    return total == 1;
  }

}
